﻿using ProtoBuf.Message;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Yunchang;

namespace AutoChess
{
    /// <summary>
    /// 战斗阶段,观战切换的过程中，当前已经行走的状态记录 用FightEntityCtr 管理 ，模拟服务器的战斗状态
    ///    当前状态机的流程阶段 每个阶段 只会走一遍， 不管是观战切换还是 整个的完成看完
    /// </summary>
     class ACShowFightState : Yunchang.FsmStateBase<AutoChessModeState>
    {
        //每个玩家的战斗状态管理
        private AutoChessManager ctr;
        private ACPlayerData enemyData;
        private ShipUnit enemyShipUnit;
        private FightState curState = FightState.None;
        private CampState campState = CampState.ALLHAVE;
        private float waitingTime = 0;
        private Action waitingCallback;
        private FightEntityCtr fightCtr; //每个玩家视角的战场状态

        private bool haveDestoryFightHero = false;
        private bool closeResultStateOnce = false;
        public FightState CurState
        {
            get { return curState; }
        }
        public ACShowFightState(AutoChessModeState stateType, AutoChessManager controller) : base(stateType, controller)
        {
            ctr = controller;
        }
        public override void Enter()
        {
            base.Enter();
            OnRegister();
            AutoChessCamera.Ins.ZoomInCamera();
            enemyShipUnit = null;
            ResetEnterState();
            fightCtr.onFightPassTimeOut = OnFightPassTimeOut;
            enemyData = ctr.cacheData.CreateEnemyPlayer(ctr.cacheData.CurPlayerData.oneMatchRes);
            AutoChessPlayerCtr.Ins.CurrentPlayer.RefreshHeroNumberState();//重新计算升星， 战场内的不能算
        }
        //战斗显示时常倒计时结束后 , 通知一下现有的 战斗结束， 同时非当前战场玩家状态设置为 战斗结束状态
        private void OnFightPassTimeOut()
        {
            EventManager.TriggerEvent(CommonEvent.ON_ON_FIGHT_REPLAY_TIMEOUT); //通知已经有的战斗退出
            fightCtr.AllFightEntityFinished();
            AutoChessFieldViewCtr.Ins.ActionCtr.StartActionQueue(ActionQueueType.EndFight, null);
        }
        private void OnRegister()
        {
            EventManager.AddEventListener(CommonEvent.ON_FIGHT_RESULT_PAGE_CLOSE, OnFightResultClose);
            EventManager.AddEventListener<long>(CommonEvent.SWITCH_AUTO_CHESS_PLAYER, OnSwitchPlayer);
            EventManager.AddEventListener(CommonEvent.ON_AUTOCHESS_BEGIN_FIGHT_COUNT_DOWN, OnFightBeginCountDown);//战斗加载完成开始回合时候触发 开始倒计时
            EventManager.AddEventListener(CommonEvent.ON_AUTOCHESS_END_FIGHT_COUNT_DOWN, OnFightEndCountDown);
        }
        private void UnRegister()
        {
            EventManager.RemoveEventListener(CommonEvent.ON_FIGHT_RESULT_PAGE_CLOSE, OnFightResultClose);
            EventManager.RemoveEventListener<long>(CommonEvent.SWITCH_AUTO_CHESS_PLAYER, OnSwitchPlayer);
            EventManager.RemoveEventListener(CommonEvent.ON_AUTOCHESS_BEGIN_FIGHT_COUNT_DOWN, OnFightBeginCountDown);
            EventManager.RemoveEventListener(CommonEvent.ON_AUTOCHESS_END_FIGHT_COUNT_DOWN, OnFightEndCountDown);
        }

        //回合开始的时候 开始倒计时
        private void OnFightBeginCountDown()
        {
            fightCtr.CalcFightTimeState = true;
            SetFieldUICamera();
            AutoChessCamera.Ins.ZoomInFightCamera();
            //Debug.LogError("收到战斗计时");
        }
        //战斗结束或者 看别的战斗切换的时候 停止倒计时
        private void OnFightEndCountDown()
        {
            fightCtr.CalcFightTimeState = false;
            SetFieldUICamera();
        }
        private void SetFieldUICamera()
        {
            SceneUIManager.Instance.SetCamera(SceneUICameraType.ThreeD, AutoChessCamera.Ins.acCamera);
        }
        //检测游戏是否结束
        private void CheckIsGameOver()
        {
            if (ctr.cacheData.overScoreData != null && ctr.cacheData.IsGameOverOpen==false)
            {
                if (AutoChessPlayerCtr.Ins.CurrentPlayer.IsSelfPlayer)
                {
                    AutoChessPlayerCtr.Ins.CurrentPlayer.ClearAllHero();
                }
                EventManager.TriggerEvent<bool>(CommonEvent.ON_SET_SHIP_GRID_PANEL, false);
                AutoChessFieldViewCtr.Ins.OpenDuanPage();
                ctr.cacheData.IsGameOverOpen = true;
            }
        }
        private void OnFightResultClose()
        {
            if (!closeResultStateOnce) //确保自动关闭或手动关闭只会进来一次
            {
                curState = FightState.CloseResultPage;
            }
        }
        private void ResetEnterState()
        {
            fightCtr = ctr.CurrentAutoChessField.fightCtr;
            fightCtr.SwitchFightEntity(ctr.cacheData.CurPlayerData.GUID);//创建每个玩家的战场数据

            closeResultStateOnce = false;//确保显示流程中只进行一次的关闭状态
            haveDestoryFightHero = false;//确保显示的流程中只有一次的英雄销毁

            campState = fightCtr.CurFightEntity.ThisCampState;  //战场阵营剩余的类别
            curState = fightCtr.CurFightEntity.CurFightState;   //当前的战斗阶段的状态
        }

        /// <summary>
        /// 切换观战玩家 ，此时自己所有的英雄已经创建
        ///     1、先判断这个玩家进行到哪个阶段
        ///     2、结算阶段直接展现结算
        /// </summary>
        /// <param name="guid"></param>
        private void OnSwitchPlayer(long guid)
        {
            //切换玩家战场状态
            fightCtr.SwitchFightEntity(guid);
            ResetEnterState();
            ctr.EnterFightFlag = false; //切换玩家的 当前战斗标识退出

            DelateCurEnemy();
            bool isHideLoading = true;

            EventManager.TriggerEvent(CommonEvent.ON_Refresh_Ship_HP_UI, guid);

            if (campState != CampState.ALLHAVE)
            {
                EventManager.TriggerEvent(CommonEvent.ON_ON_FIGHT_REPLAY_TIMEOUT);
            }

            if (curState == FightState.DirectResult)
            {
                UtilityHelper.PlayBackGround();
                CreateNewEnemy(ctr.cacheData.CurPlayerData.oneMatchRes, ctr.cacheData.CurPlayerData.oneFightResult.right.resultChess);
                HideCurPlayer();
                EventManager.TriggerEvent(CommonEvent.ON_CUR_FIGHT_END);//发送战斗结束 通知UI显示
                curState = FightState.None;
                AutoChessCamera.Ins.SwitchCamera(CameraState.HighterFightState);
                CheckIsGameOver();
            }
            else if (curState >= FightState.CreateShip && curState <= FightState.WaitForFightEnd) // 切换了 战斗状态前就全部直接走战斗
            {
                isHideLoading = false;//由战斗逻辑控制隐藏，等战斗那边资源加载完成隐藏
                CreateNewEnemy(ctr.cacheData.CurPlayerData.oneMatchRes);//需要创建完整的玩家
                OnEnterFight();//进入 战斗
                curState = FightState.WaitForFightEnd;
                ctr.EnterFightFlag = true;
                AutoChessCamera.Ins.SwitchCamera(CameraState.LowerFightState);
            }
            if (isHideLoading)
                LoadingPanel.Instance.HiedCloudMask(0.6f);
            SetFieldUICamera();
        }
        private void DelateCurEnemy()
        {
            if (enemyShipUnit != null)
                enemyShipUnit.DisconnectRenderer();
            AutoChessPlayerCtr.Ins.DelateEnemyPlayer();
        }
        /// <summary>
        /// 创建敌人
        /// </summary>
        /// <param name="matchRes"></param>
        /// <param name="left"></param>
        private void CreateNewEnemy(SCAutoChessMatchRes matchRes, List<AutoChessChessInfo> left = null)
        {
            enemyData = ctr.cacheData.CreateEnemyPlayer(matchRes, left);
            AutoChessPlayerCtr.Ins.EnemyPlayer = AutoChessPlayerCtr.Ins.CreateEnemyEntityPlayer(enemyData);
            enemyShipUnit = AutoChessPlayerCtr.Ins.CreateShipUnit(enemyData.ShipId, AutoChessFieldViewCtr.Ins.SceneConfig.targetPos.position, AutoChessPlayerCtr.Ins.EnemyPlayer);
        }
        private void HideCurPlayer()
        {
            AutoChessPlayerCtr.Ins.CurrentPlayer.HeroDeath(ctr.cacheData.CurPlayerData.oneFightResult.left.resultChess);
        }
        private void DebugLog(string text)
        {
            ExLog.LogV(string.Format("<color=red> {0} </color>", text));
        }
        private void OnEnterFight()
        {
            AutoChessPlayerCtr.Ins.EnemyPlayer.GridHeroDisconnectRenderer(GridType.EnemyGrid);
            AutoChessPlayerCtr.Ins.CurrentPlayer.GridHeroDisconnectRenderer(GridType.FightGrid); //进入战斗断开渲染器
            haveDestoryFightHero = true;
            //AutoChessFieldViewCtr.Ins.DestroyHeroShipHidedUnitRenderer(); //清除没用的表现缓存
            FightReplayManager.Instance.RequestAutoChessFightReplay(ctr.cacheData.CurPlayerData.oneFightResult.fightId, fightCtr.EnterNormalizeFightTime);
            EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESS_END_FIGHT_COUNT_DOWN);//每次
        }
        public override void Update()
        {
            fightCtr.OnTickFightEntty();
            if (curState == FightState.CreateShip)
            {
                //解析对手数据 创建船只
                if (enemyData.ShipId == 0)
                {
                    enemyData.ShipId = Table.DataModel.TableConfig.autochessDefaultShip ;
                }
                CreateNewEnemy(ctr.cacheData.CurPlayerData.oneMatchRes);//创建所有的敌人
                AutoChessPlayerCtr.Ins.EnemyPlayer.HideAllEnemy();//创建了隐藏敌人
                curState = FightState.ShipComming;
            }
            else if (curState == FightState.ShipComming)//船只开进来
            {
                enemyShipUnit.AutoPath(UtilityHelper.GetComeCurve(), () =>
                {
                    curState = FightState.EnemyEnter;
                });
                waitingTime = 99f;
                curState = FightState.Wating;
            }
            else if (curState == FightState.EnemyEnter)//创建玩家入场 等待
            {
                curState = FightState.Wating;
                AutoChessPlayerCtr.Ins.EnemyPlayer.ShowAllEnemy();

                AutoChessPlayerCtr.Ins.EnemyPlayer.OnUpStarBuff(ctr.cacheData.CurPlayerData.oneMatchRes.levelUpRight); //升星buff
                AutoChessPlayerCtr.Ins.CurrentPlayer.OnUpStarBuff(ctr.cacheData.CurPlayerData.oneMatchRes.levelUpLeft);//升星buff

               // LoadingPanel.Instance.ShowCloudMask();

                waitingTime = AutoChessFieldViewCtr.Ins.SceneConfig.showHeroTime;
                waitingCallback = () =>
                {
                    if (campState == CampState.ALLHAVE) //双方都有人请求战斗
                    {
                        curState = FightState.BeginFight;
                    }
                    else //一边没人 直接显示场景 战斗结果
                    {
                        if (LoadingPanel.Instance.IsCloudMaskShow())
                        {
                            LoadingPanel.Instance.HiedCloudMask(0.5f);
                        }
                        var resId = ctr.cacheData.CurPlayerData.oneFightResult.leftWin == true ? CommonEffectResId.AC_Fight_UI_Win : CommonEffectResId.AC_Fight_Lose;
                        EventManager.TriggerEvent<CommonEffectResId>(CommonEvent.ON_PLAY_UI_EFFECT, resId);
                        curState = FightState.SceneResult;
                    }
                    EventManager.TriggerEvent(CommonEvent.ON_CUR_FIGHT_END);//发送战斗结束消息
                };
            }
            else if (curState == FightState.BeginFight)// 进入到战斗
            {
                LoadingPanel.Instance.ShowCloudMask();
                //EventManager.TriggerEvent<CommonEffectResId>(CommonEvent.ON_PLAY_UI_EFFECT, CommonEffectResId.AC_Rund_Begin);

                curState = FightState.Wating;
                waitingTime = AutoChessFieldViewCtr.Ins.SceneConfig.battleMaskDelayTime;
                waitingCallback = () =>
                 {
                     OnEnterFight();//进入 战斗
                    curState = FightState.WaitForFightEnd;
                 };

                ctr.EnterFightFlag = true;
            }
            else if (curState == FightState.WaitForFightEnd)
            {
                if (ctr.EnterFightFlag == false) //退出战斗
                {
                    EventManager.TriggerEvent(CommonEvent.ON_CUR_FIGHT_END);
                    curState = FightState.EndFighting;
                }
            }
            else if (curState == FightState.Wating)
            {
                waitingTime -= Time.unscaledDeltaTime;
                if (waitingTime <= 0)
                {
                    waitingCallback();
                    waitingCallback = null;
                }
            }
            else if (curState == FightState.EndFighting)
            {
                // 防止云雾切屏没有隐藏一直显示
                if (LoadingPanel.Instance.IsCloudMaskShow())
                {
                    LoadingPanel.Instance.HiedCloudMask();
                }
                AutoChessCamera.Ins.ZoomOutFightCamera();

                //把战场上的英雄重新生成 然后隐藏死亡的人
                AutoChessPlayerCtr.Ins.EnemyPlayer.GridHeroReconnectRenderer(GridType.EnemyGrid); //进入战斗链接渲染器
                AutoChessPlayerCtr.Ins.EnemyPlayer.HeroDeath(ctr.cacheData.CurPlayerData.oneFightResult.right.resultChess, true);//敌人死亡

                AutoChessPlayerCtr.Ins.CurrentPlayer.GridHeroReconnectRenderer(GridType.FightGrid);// 重新链接渲染器
                AutoChessPlayerCtr.Ins.CurrentPlayer.HeroDeath(ctr.cacheData.CurPlayerData.oneFightResult.left.resultChess); //自己死亡

                AutoChessFieldViewCtr.Ins.ActionCtr.StartActionQueue(ActionQueueType.EndFight, null);
                haveDestoryFightHero = false;
                curState = FightState.Wating;
                waitingTime = AutoChessFieldViewCtr.Ins.SceneConfig.fightEndShowResult;
                waitingCallback = () => { curState = FightState.ResultPage; };
                DebugLog(curState.ToString());
            }
            else if (curState == FightState.ResultPage)
            {
                if (AutoChessManager.Ins.cacheData.CurPlayerData.GUID == StaticData.playerData.playerId) // 只有自己需要打开结果面板
                {
                    if (campState == CampState.ALLHAVE && AutoChessManager.Ins.cacheData.fighResult != null)
                        PageManager.Instance.OpenPage("ChessResultPage", AutoChessManager.Ins.cacheData.fighResult);
                }
                curState = FightState.Wating;
                waitingTime = AutoChessFieldViewCtr.Ins.SceneConfig.resultPageShowTime;
                waitingCallback = () => { curState = FightState.CloseResultPage; };
                DebugLog(curState.ToString());
            }
            else if (curState == FightState.CloseResultPage)
            {
                if (closeResultStateOnce) //确保自动关闭或手动关闭只会进来一次
                {
                    return;
                }
                closeResultStateOnce = true;
                PageManager.Instance.ClosePage("ChessResultPage");
                curState = FightState.Wating;
                waitingTime = AutoChessFieldViewCtr.Ins.SceneConfig.closePage2SceneResult;
                waitingCallback = () => { curState = FightState.SceneResult; };
                DebugLog(curState.ToString());
            }
            else if (curState == FightState.SceneResult)
            {
                //疲劳
                EventManager.TriggerEvent(CommonEvent.ON_SHIP_TIRED_EVENT);

                AutoChessPlayerCtr.Ins.EnemyPlayer.OffUpStarBuff(ctr.cacheData.CurPlayerData.oneMatchRes.right.resultChess); //升星buff
                AutoChessPlayerCtr.Ins.CurrentPlayer.OffUpStarBuff(ctr.cacheData.CurPlayerData.oneMatchRes.left.resultChess);//升星buff

                if (ctr.cacheData.CurPlayerData.oneFightResult.leftWin == true)
                {
                    EventManager.TriggerEvent(CommonEvent.ON_Refresh_Cache_HP);
                    CommonEffectManager.Instance.PlayEffectImmediate(CommonEffectResId.AC_Fight_Scene_Win, AutoChessPlayerCtr.Ins.CurrentPlayer.ShipUnit.ShipRenderer.transform);
                }
                else
                {
                    enemyShipUnit.FireTheHole(AutoChessPlayerCtr.Ins.CurrentPlayer.ShipUnit, AutoChessFieldViewCtr.Ins.SceneConfig.enemyHitSelf_Curve);//敌人射击自己
                }
                curState = FightState.Wating;
                waitingTime = AutoChessFieldViewCtr.Ins.SceneConfig.sceneShowResultTime;
                waitingCallback = () =>
                {
                    curState = FightState.None; //战斗表现结束
                    UtilityHelper.PlayBackGround();
                    AutoChessManager.Ins.SendCSAutoChessFightFinish();
                    //暂且是第一个看完流程的时候 就算结束了
                    fightCtr.AllFightEntityFinished();
                    CheckIsGameOver();
                };
                DebugLog(curState.ToString());
            }
            else if (curState == FightState.DirectResult) //直接显示战斗结果
            {
                //敌人剩余的数据
                enemyData = ctr.cacheData.CreateEnemyPlayer(ctr.cacheData.CurPlayerData.oneMatchRes, ctr.cacheData.CurPlayerData.oneFightResult.right.resultChess);
                AutoChessPlayerCtr.Ins.CreateEnemyEntityPlayer(enemyData);//创建自己
                enemyShipUnit = AutoChessPlayerCtr.Ins.CreateShipUnit(enemyData.ShipId, AutoChessFieldViewCtr.Ins.SceneConfig.targetPos.position, null);
                AutoChessPlayerCtr.Ins.CurrentPlayer.HeroDeath(ctr.cacheData.CurPlayerData.oneFightResult.left.resultChess); //自己死亡
                curState = FightState.None;
            }
        }

        /// <summary>
        /// 结束的时候 需要强制处理 结果
        /// </summary>
        public override void Leave()
        {
           
            UtilityHelper.PlayBackGround();
            if (fightCtr != null)
            {
                fightCtr.OnDestroyAllFightEntity();
            }
            EventManager.TriggerEvent(CommonEvent.ON_ON_FIGHT_REPLAY_TIMEOUT); // 通知一下战斗退出

            UnRegister();
            base.Leave();
            EnemyLeave();
            if (haveDestoryFightHero)
            {
                AutoChessPlayerCtr.Ins.CurrentPlayer.GridHeroReconnectRenderer(GridType.FightGrid);
            }
            AutoChessPlayerCtr.Ins.CurrentPlayer.HeroRelife();
            PageManager.Instance.ClosePage("ChessResultPage");
            ctr.EnterFightFlag = false;
            CheckIsGameOver();
        }
        private void EnemyLeave()
        {
            if (enemyShipUnit != null)
            {
                enemyShipUnit.AutoPath(UtilityHelper.GetLeaveCurve(), () =>
                {
                    enemyShipUnit.DisconnectRenderer();
                    enemyShipUnit = null;
                });//船离开
            }
            AutoChessCamera.Ins.ZoomOutCamera();
            AutoChessPlayerCtr.Ins.DelateEnemyPlayer();
        }
    }
}
